package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.item.service.CacheService;
import com.atguigu.gmall.product.vo.SkuDetailVo;
import com.sun.media.jfxmedia.logging.Logger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class CacheServiceImpl implements CacheService {

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 从redis缓存中获取商品详情数据
     * @param skuId
     * @return
     */
    @Override
    public SkuDetailVo getFromCache(Long skuId) {
        //1、查询缓存
        String json = redisTemplate.opsForValue().get(RedisConst.SKU_DETAIL_CACHE + skuId);
        if(StringUtils.isEmpty(json)) {
            //缓存中没有
            return null;
        }else if("x".equals(json)) {
            return new SkuDetailVo(); //返回空对象
        }else {
            log.info("缓存命中");
            return JSON.parseObject(json,SkuDetailVo.class);
        }
    }

    @Override
    public boolean mightContain(Long skuId) {
        return redisTemplate.opsForValue().getBit(RedisConst.SKUID_BITMAP,skuId);

    }

    @Override
    public void save(Long skuId, SkuDetailVo returnVal) {
        //如果returnVal为null,表示布隆过滤器误判了,则缓存中也要保存，
        // 防止缓存穿透(从缓存中读一个数据，缓存没有，穿透缓存去回源查询)，不能跟本来从缓存查询为null混淆
        String jsonString = "x"; //默认是x
        if(returnVal != null) {
            jsonString = JSON.toJSONString(returnVal); //真正json
        }
        redisTemplate.opsForValue().set(RedisConst.SKU_DETAIL_CACHE + skuId,jsonString, 7,TimeUnit.DAYS);
    }
}
